#ifndef ABSTRACTTABLE_H
#define ABSTRACTTABLE_H

#include <QObject>
#include <QSqlDatabase>
#include <QSqlRecord>
#include <QVariant>
#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
#include <QMetaType>

/*
 * 借助下面这些宏，可以快速定义读写某单元格的数据，指定主键的值锁定行，指定列名锁定列。
 * 像这样：INT_CELL(role,setRole,"Id","Role")
 * 定义了两个方法
 * int role(const QVariant &primargVal);
 * void setRole(const QVariant &primargVal,const QVariant &updateVal);
*/

#define STRING_CELL(getter,setter,primaryColumnName,keyColumnName) \
QString getter(const QVariant &primaryVar){ \
    return queryColumn(primaryColumnName,primaryVar,keyColumnName).toString(); \
} \
void setter(const QVariant &primaryVar,QVariant val){ \
    updateColumn(primaryColumnName,primaryVar,keyColumnName,val); \
}
#define INT_CELL(getter,setter,primaryColumnName,keyColumnName) \
int getter(const QVariant &primaryVar){ \
    return queryColumn(primaryColumnName,primaryVar,keyColumnName).toInt(); \
} \
void setter(const QVariant &primaryVar,QVariant val){ \
    updateColumn(primaryColumnName,primaryVar,keyColumnName,val); \
}
#define BOOL_CELL(getter,setter,primaryColumnName,keyColumnName) \
bool getter(const QVariant &primaryVar){ \
    return queryColumn(primaryColumnName,primaryVar,keyColumnName).toBool(); \
} \
void setter(const QVariant &primaryVar,QVariant val){ \
    updateColumn(primaryColumnName,primaryVar,keyColumnName,val); \
}

class AbstractTable : public QObject
{
    Q_OBJECT
public:
    explicit AbstractTable(const QString &tableName,QObject *parent = nullptr);

    bool createTable(const QString &createTabelSql);  //创建表
    bool dropTable();                   //删除表
    bool clearTable();                  //清空表中的所有数据
    bool exists();                      //表是否存在
    int count();                        //表中数据行数

    bool execSql(QString strSql);       //执行无返回结果的SQL语句
    bool transaction();                 //开启事务
    bool commit();
    bool rollback();

    virtual bool addRow(const QVariantMap &rowData);
    virtual bool deleteRow(const QString &primaryColumnName,QVariant var);
    virtual bool updateRow(const QString &primaryColumnName,QVariant var,QVariantMap row);
    virtual QSharedPointer<QVariantMap> queryRow(QString primaryColumnName,QVariant var);
    virtual QSharedPointer<QList<QVariantMap> > queryAll();
    virtual QVariant queryColumn(QString primaryColumnName,QVariant var,QString columnName);
    virtual bool updateColumn(QString primaryColumnName, QVariant primaryVar,
                              QString columnName, QVariant newVar);

protected:
    QSqlDatabase *dbConnection();       //获取当前线程中的数据库连接
protected:
    const QString m_strTableName;
};

#endif // ABSTRACTTABLE_H
